#pragma once
#include"preCmpH.h"
#include"UIRenderer.h"
#include"UIEventManager.h"
#include"UIFontManager.h"
// controls
#include"UIControlContainer.h"
#include"UILabel.h"
#include"UIButton.h"
#include"UITextbox.h"

BEGIN_NAMESPACE(ui_manager)

class UIManager;
typedef std::shared_ptr<UIManager> UIManagerSharedPtr; // Shared pointer to manage the UIManager

//========== Description ==========
//PURPOSE : Manage`s UI elements and UI subsystems
//REQUIRE : Nothing
//PROMISE : Nothing
class UIManager
{
public:
//=====================================
// Constructors, Destructor, Operators
//=====================================

	//========== Description ==========
	//PURPOSE : None ( Use StartUp )
	//REQUIRE : Nothing
	//PROMISE : Nothing
	UIManager();
	//========== Description ==========
	//PURPOSE : None ( Use ShutDown )
	//REQUIRE : Nothing
	//PROMISE : Nothing
	~UIManager();
//=====================================
// Functionality
//=====================================

	//========== Description ==========
	//PURPOSE : Start up the manager
	//REQUIRE : Nothing
	//PROMISE : Start up all the other subsystems
	void StartUp();
	//========== Description ==========
	//PURPOSE : Shut down manager
	//REQUIRE : Nothing
	//PROMISE : Clean up
	void ShutDown();
	//========== Description ==========
	//PURPOSE : Bind a UIControl or derivate class to the manager
	//REQUIRE : UIControl pointer
	//PROMISE : Bind the control specified and maybe his hierarchy
	void Bind(ui_controls::UIControl* toBind);
	//========== Description ==========
	//PURPOSE : Unbind a UIControl
	//REQUIRE : Non-null string
	//PROMISE : Unbind the control with the specified name
	void Unbind(std::string control_name);
	//========== Description ==========
	//PURPOSE : Destroy the current UI
	//REQUIRE : Nothing
	//PROMISE : Destroy all UI elements and their resources
	void Clear();
	//========== Description ==========
	//PURPOSE : Process stored events
	//REQUIRE : UIInputManager used for OS input events
	//PROMISE : Post stored events to controls
	void ProcessEvents();
	//========== Description ==========
	//PURPOSE : None
	//REQUIRE : Nothing
	//PROMISE : Nothing
	ui_controls::UIControlContainer& getRoot();
//=====================================
// Getters
//=====================================

	//========== Description ==========
	//PURPOSE : None
	//REQUIRE : Nothing
	//PROMISE : Nothing
	ui_fonts::UIFontManager& getUIFontManager();
	//========== Description ==========
	//PURPOSE : None
	//REQUIRE : Nothing
	//PROMISE : Nothing
	ui_graphics::UIRenderer& getUIRenderer();
	//========== Description ==========
	//PURPOSE : None
	//REQUIRE : Nothing
	//PROMISE : Nothing
	ui_events::UIEventManager& getUIEventManager();
	//========== Description ==========
	//PURPOSE : Get instance of the UIManager
	//REQUIRE : Nothing
	//PROMISE : Return the instance of the UIManager
	static UIManager& getInstance();

private:
	UIManager(const UIManager&); // denied
	UIManager& operator= (const UIManager&); // denied
	void TestInvariant() const;

	ui_controls::UIControlContainer root_;

	ui_graphics::UIRenderer* renderer_;
	ui_fonts::UIFontManager* fontManager_;
	ui_events::UIEventManager* eventManger_;

	bool started_;
};

END_NAMESPACE